package cn.tedu.rms.message;

import cn.tedu.rms.base.util.JacksonUtil;
import cn.tedu.rms.base.util.SpringContextUtils;
import cn.tedu.rms.message.pojo.MessageFrom;
import cn.tedu.rms.message.pojo.MessageToCustomer;
import cn.tedu.rms.message.pojo.MessageToSer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

@Component
@Slf4j
//@ServerEndpoint创建WebSocket端点
//当客户端连接到路径/ws/server/{userId}时，就会触发WebSocketServer中的相应方法
@ServerEndpoint("/ws/message/{userIdRoleBranchId}")//  /ws/message/{101_1_107}
public class WebSocketServer {

    /*private static UserMapper userMapper;

    @Autowired
    public void setUserMapper(UserMapper userMapper){
        WebSocketServer.userMapper = userMapper;
    }*/



    private static final ConcurrentHashMap<Long,Session> sessionCustomerMap = new ConcurrentHashMap<>();
    //private static final ConcurrentHashMap<Long,Session> sessionSerMap = new ConcurrentHashMap<>();
    // 创建一个 LinkedHashMap 实例 ,确保顺序
    // 使用 Collections.synchronizedMap() 方法将其变为线程安全
    private static final ConcurrentHashMap<String,Session> sessionSerMap = new ConcurrentHashMap<>();
    private static final ConcurrentHashMap<Long,Long> customerSerMap = new ConcurrentHashMap<>();

    @OnOpen
    public void opOpen(@PathParam("userIdRoleBranchId") String userIdRoleBranchId, Session session){
        log.debug("用户：{}，建立连接",userIdRoleBranchId);
        String[] split = userIdRoleBranchId.split("_");
        Long branchId = new Long(split[2]);//分店id
        String role = split[1];//角色
        Long userId = new Long(split[0]);//用户id
        if("1".equals(role)){
            sessionCustomerMap.put(userId,session);
            //顾客
            Long serId = customerSerMap.get(userId);//顾客绑定的客服id
            if(serId!=null){
                //已经绑定了客服
            }else{
                if(!sessionSerMap.isEmpty()){
                    // 将 entrySet 中满足条件值放到 List
                    Set<Map.Entry<String, Session>> entrySet = sessionSerMap.entrySet();
                    List<Long> serIdSatisfyList = new ArrayList<>();
                    for (Map.Entry<String, Session> m : entrySet) {
                        String key = m.getKey();//  102_107   用户id_分店id
                        Session value = m.getValue();
                        Long serBranchId = new Long(key.split("_")[1]);
                        if(serBranchId.equals(branchId)){
                            Long serIdSatisfy = new Long(key.split("_")[0]);
                            serIdSatisfyList.add(serIdSatisfy);
                        }
                    }
                    if(!serIdSatisfyList.isEmpty()){
                        Long index = userId%serIdSatisfyList.size();
                        Long bindSerId = serIdSatisfyList.get((int) index.longValue());
                        customerSerMap.put(userId,bindSerId);//绑定顾客和客服
                        log.debug("顾客和客服绑定集合：{}",customerSerMap);
                        sendMessageUseMachine(userId,"客服在线,有什么问题欢迎咨询");

                        new WebSocketCheckJob(userId);//有5分钟时间,5分钟自动断开
                    }else {
                        log.debug("该分店客服没有上线");
                        sendMessageUseMachine(userId,"客服不在线哟~，请稍后联系我们");
                        disconnectUser(userId);//断开顾客的会话

                    }
                }else{
                    log.debug("所有分店客服都没有上线");
                    sendMessageUseMachine(userId,"客服不在线哟~，请稍后联系我们");
                    disconnectUser(userId);//断开顾客的会话

                }
            }
        }else if("2".equals(role)) {
            String serStr = userId+"_"+branchId;
            sessionSerMap.put(serStr,session);
        }

    }
    @OnClose
    public void onClose(@PathParam("userIdRoleBranchId") String userIdRoleBranchId, Session session){
        log.debug("用户：{}，关闭连接",userIdRoleBranchId);
        String[] split = userIdRoleBranchId.split("_");
        Long branchId = new Long(split[2]);//分店id
        String role = split[1];
        Long userId = new Long(split[0]);
        if("1".equals(role)){
            sessionCustomerMap.remove(userId,session);//从sessionCustomerMap中移除
            customerSerMap.remove(userId);//取消顾客与客服的绑定
        }else if("2".equals(role)) {
            sessionSerMap.remove(userId+"_"+branchId,session);
        }
    }
    @OnMessage
    public void onMessage(Session session,String message){
        log.debug("用户,{}发送消息：{}",session,message);

        MessageFrom messageFrom = null;
        try {
            messageFrom = JacksonUtil.fromJson(message, MessageFrom.class);
        } catch (Exception e) {
            log.error("消息转换失败",e);
        }
        if("1".equals(messageFrom.getRole())){
            Long customerId = messageFrom.getUserId();
            Long branchId = messageFrom.getBranchId();

            MessageToSer messageToSer = new MessageToSer();
            messageToSer.setMessage(messageFrom.getMessage());
            messageToSer.setCustomerName(messageFrom.getUsername());
            messageToSer.setCustomerId(messageFrom.getUserId());
            String jsonMessageToSer = JacksonUtil.toJson(messageToSer);
            Long serId = customerSerMap.get(messageFrom.getUserId());
            sendMessageToSer(customerId,serId,branchId,jsonMessageToSer);
        }else if("2".equals(messageFrom.getRole())){
            Long customerId = messageFrom.getToWho();

            MessageToCustomer messageToCustomer = new MessageToCustomer();
            messageToCustomer.setMessage(messageFrom.getMessage());
            messageToCustomer.setSerName(messageFrom.getUsername());
            String jsonMessageToCustomer = JacksonUtil.toJson(messageToCustomer);
            Long serId = messageFrom.getUserId();
            Long branchId = messageFrom.getBranchId();
            sendMessageToCustomer(customerId,serId,branchId,jsonMessageToCustomer);
        }
    }
    @OnError
    public void onError(Session session,Throwable throwable){
        log.debug("用户，{},连接异常",session,throwable);
    }


    /**
     * 机器自动回复
     * @param customerId
     * @param message
     */
    public void sendMessageUseMachine(Long customerId,String message){
        Session session = sessionCustomerMap.get(customerId);
        if(session!=null){
            MessageToCustomer messageToCustomer = new MessageToCustomer();
            messageToCustomer.setMessage(message);
            messageToCustomer.setSerName("机器人");
            messageToCustomer.setSerId(0L);
            String jsonMessageToCustomer = JacksonUtil.toJson(messageToCustomer);
            session.getAsyncRemote().sendText(jsonMessageToCustomer);
        }else {
            log.debug("用户不在线");
            //保存到数据库
        }
    }
    public void sendMessageUseMachineToSer(Long serId,Long branchId,String message){
        Session session = sessionSerMap.get(serId+"_"+branchId);
        if(session!=null){
            MessageToCustomer messageToCustomer = new MessageToCustomer();
            messageToCustomer.setMessage(message);
            messageToCustomer.setSerName("机器人");
            messageToCustomer.setSerId(0L);
            String jsonMessageToCustomer = JacksonUtil.toJson(messageToCustomer);
            session.getAsyncRemote().sendText(jsonMessageToCustomer);
        }else {
            log.debug("客服不在线");
            //保存到数据库
        }
    }
    public void sendMessageToSer(Long customerId, Long serId,Long branchId,String message){
        Session session = sessionSerMap.get(serId+"_"+branchId);
        if(session!=null){
            session.getAsyncRemote().sendText(message);
        }else {
            log.debug("用户不在线");
            log.debug("通知顾客");
            sendMessageUseMachine(customerId,"客服不在线哟~，请稍后联系我们");
            disconnectUser(customerId);//断开顾客的会话
        }
    }

    public void sendMessageToCustomer(Long customerId,Long serId,Long branchId,String message){
        Session session = sessionCustomerMap.get(customerId);
        if(session!=null){
            session.getAsyncRemote().sendText(message);
        }else {
            log.debug("用户不在线");
            log.debug("通知客服");
            sendMessageUseMachineToSer(serId,branchId,"顾客已下线~");
        }
    }
    public void disconnectUser(Long userId){
        Session session = sessionCustomerMap.get(userId);
        if(session!=null&&session.isOpen()){
            try {
                session.close();
                sessionCustomerMap.remove(userId,session);//从sessionCustomerMap中移除
                customerSerMap.remove(userId);//取消顾客与客服的绑定
                log.debug("服务器主动关闭用户：{}的连接",userId);
            } catch (IOException e) {
                log.debug("关闭异常");
            }
        }
    }
}
